package com.zwh.rabbitmq.basic.consumer;

import com.rabbitmq.client.Channel;
import com.zwh.rabbitmq.basic.dto.ProjectInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * 消费者demo2
 * @RabbitListener + @RabbitHandler 注解结合使用
 *
 * @RabbitListener标记在类级别时，需要和 @RabbitHandler注解结合使用
 * @author zwh
 * @date 2022/1/31
 */
@Slf4j
@Component
@RabbitListener(queues = "project.info.delete")
public class TestListener2 {

    @RabbitHandler
    public void testListenerHandler0(Message message, Channel channel) throws IOException {
        // 手动ack， 需要传递消息序列号， false表示只对当前这个消息进行响应（不对序列号之前的消息进行批量处理）。
        log.info("testListenerHandler1=========无参数" + message.toString());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    /**
     * 匹配类型为 没有注解修饰的第一个参数
     *
     * note: 当无注解的第一个参数类型和 有加@Payload注解的参数类型一样时。
     * 该队列有消息进来时，会抛出异常，org.springframework.amqp.AmqpException: Ambiguous methods for payload type：
     *          class com.zwh.rabbitmq.basic.dto.ProjectInfoDto: testListenerHandler2 and testListenerHandler1
     *
     *  模棱两可的处理指定类型的方法。 如这个 testListenerHandler1(ProjectInfoDto projectInfoDto, Message message, Channel channel)方法
     *  和 testListenerHandler2(@Payload ProjectInfoDto projectInfoDto, Message message, Channel channel)方法
     *
     *  解决方法：去掉其中一个之后就能正常使用。
     * @param projectInfoDto
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitHandler
    public void testListenerHandler1(ProjectInfoDto projectInfoDto, Message message, Channel channel) throws IOException {
        // 手动ack， 需要传递消息序列号， false表示只对当前这个消息进行响应（不对序列号之前的消息进行批量处理）。
        log.info("testListenerHandler1=========有参数" + message.toString());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    /**
     * 匹配类型为 @Payload 注解修饰的类型
     * @param projectInfoDto
     * @param message
     * @param channel
     * @throws IOException
     */
//    @RabbitHandler
//    public void testListenerHandler2(@Payload ProjectInfoDto projectInfoDto, Message message, Channel channel) throws IOException {
//        // 手动ack， 需要传递消息序列号， false表示只对当前这个消息进行响应（不对序列号之前的消息进行批量处理）。
//        log.info("testListenerHandler1=========有注解参数" + message.toString());
//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//    }

    /**
     * 匹配类型为 @Payload 注解修饰的类型
     * @param projectInfoDto
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitHandler
    public void testListenerHandler3(@Payload Map<String, Object> projectInfoDto,
                              Message message, Channel channel) throws IOException {
        // 手动ack， 需要传递消息序列号， false表示只对当前这个消息进行响应（不对序列号之前的消息进行批量处理）。
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
